package com.heima.article.logUtil;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.jboss.logging.MDC;
import org.springframework.stereotype.Component;

/**
 * 日志切面类：用于在进入 service 方法时自动设置 MDC 上下文中的 serviceName，
 * 以便 Logback 动态生成按服务名分隔的日志文件。
 */
@Aspect        // 标识这是一个切面类（Aspect）
@Component     // 将该类纳入 Spring 容器管理，自动注册为 Bean
public class LoggingAspect {

    /**
     * 定义 MDC 中用于存储服务名称的键（Key）。
     * 这个 key 需要与 logback.xml 中配置的 discriminator 的 key 保持一致。
     */
    private static final String SERVICE_NAME_MDC_KEY = "serviceName";

    /**
     * 在执行 com.heima.user.service 包及其子包下的任意方法前触发此通知（Advice）。
     * 用于设置 MDC 上下文中的 serviceName。
     */
    @Before("execution(* com.heima.user.service..*.*(..))")
    public void beforeServiceCall(JoinPoint joinPoint) {
        // 获取被调用的目标对象的类名（例如 UserServiceImpl）
        String className = joinPoint.getTarget().getClass().getSimpleName();

        // 如果类名以 "Impl" 结尾，则去掉 "Impl"
        if (className.endsWith("Impl")) {
            className = className.substring(0, className.length() - 4);
        }

        // 移除"Impl"后缀（如果存在）
        if (className.endsWith("Impl")) {
            className = className.substring(0, className.length() - 4);
        }

        // 将首字母转为小写
        if (!className.isEmpty()) {
            className = Character.toLowerCase(className.charAt(0)) + className.substring(1);
        }

        // 将处理后的服务名写入MDC
        MDC.put(SERVICE_NAME_MDC_KEY, className);
    }

    /**
     * 在执行完 com.heima.user.service 包及其子包下的任意方法后触发此通知（Advice）。
     * 用于清理 MDC 上下文，避免内存泄漏或日志混乱。
     */
    @After("execution(* com.heima.user.service..*.*(..))")
    public void afterServiceCall() {
        // 清除当前线程的 MDC 上下文，防止影响其他请求
        MDC.clear();
    }
}
